package com.umeox.ota.service;

import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;

import androidx.annotation.Nullable;

import com.abupdate.iot_libs.OtaAgentPolicy;
import com.abupdate.iot_libs.data.local.DeviceInfo;
import com.abupdate.iot_libs.data.local.ProductInfo;
import com.abupdate.iot_libs.data.remote.VersionInfo;
import com.abupdate.iot_libs.engine.otaStatus.OtaStatusMgr;
import com.abupdate.iot_libs.interact.callback.ICheckVersionCallback;
import com.abupdate.iot_libs.interact.callback.IRebootUpgradeCallBack;
import com.abupdate.trace.Trace;
import com.umeox.ota.ICheckVersionAidlInter;
import com.umeox.ota.IDownloadAidlInter;
import com.umeox.ota.IGetDeviceInfoAidlInter;
import com.umeox.ota.IOtaInter;
import com.umeox.ota.IUpdateAidlInter;
import com.umeox.ota.data.constant.TRIGGER;
import com.umeox.ota.data.local.DeviceAidlInfo;
import com.umeox.ota.interact.callback.IDownloadInter;
import com.umeox.ota.utils.RxTime;
import com.umeox.ota.utils.Utils;

import java.util.List;

/**
 * @author fighter_lee
 * @date 2018/7/10
 */
public class OtaAidlService extends Service {

    private static final String TAG = "OtaAidlService";

    IGetDeviceInfoAidlInter iGetDeviceInfoAidlInter;
    ICheckVersionAidlInter iCheckVersionAidlInter;
    IDownloadAidlInter iDownloadAidlInter;
    IUpdateAidlInter iUpdateAidlInter;
    OtaService.OtaBinder otaBinder;

    ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            otaBinder = (OtaService.OtaBinder) iBinder;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            otaBinder = null;
        }
    };

    private void checkVersionTask() {
        Trace.d(TAG, "checkVersionTask() ");
        if (!aidlPrepare()) {
            return;
        }
        otaBinder.checkVersion(TRIGGER.CHECK.CHECK_AIDL, new ICheckVersionCallback() {

            @Override
            public void onCheckSuccess(List<VersionInfo> list) {
                if (null != iCheckVersionAidlInter) {
                    try {
                        iCheckVersionAidlInter.hasNewVersion(Utils.toAidlInfo(list.get(0)));
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onCheckFail(int i) {
                if (null != iCheckVersionAidlInter) {
                    try {
                        iCheckVersionAidlInter.noNewVersion(i);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }


    private void downloadTask() {
        Trace.d(TAG, "downloadTask() ");
        if (!aidlPrepare()) {
            return;
        }
        otaBinder.download(TRIGGER.DOWNLOAD.DOWNLOAD_AIDL, new IDownloadInter() {
            @Override
            public void onStart() {
                if (null != iDownloadAidlInter) {
                    try {
                        iDownloadAidlInter.onStart();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onSuccess() {
                if (null != iDownloadAidlInter) {
                    try {
                        iDownloadAidlInter.onSuccess();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onDownloadProgress(int progress) {
                if (null != iDownloadAidlInter) {
                    try {
                        iDownloadAidlInter.onProgress(progress);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onFailed(int code) {
                if (null != iDownloadAidlInter) {
                    try {
                        iDownloadAidlInter.onFail(code);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onCancel() {
                if (null != iDownloadAidlInter) {
                    try {
                        iDownloadAidlInter.onCancel();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    private void installTask() {
        Trace.d(TAG, "installTask() ");
        if (!aidlPrepare()) {
            return;
        }
        otaBinder.upgrade(TRIGGER.UPGRADE.UPGRADE_AIDL, new IRebootUpgradeCallBack() {
            @Override
            public boolean rebootConditionPrepare() {
                return true;
            }

            @Override
            public void onUpgrading(float v) {
                if (null != iUpdateAidlInter) {
                    try {
                        iUpdateAidlInter.upgradeProgress((int) v);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onSuccess() {
                if (null != iUpdateAidlInter) {
                    try {
                        iUpdateAidlInter.upgradeSuccess();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onError(int i) {
                if (iUpdateAidlInter != null) {
                    try {
                        iUpdateAidlInter.enterRecoveryFail(i);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    IOtaInter.Stub iOtaInter = new IOtaInter.Stub() {
        @Override
        public void getDeviceInfo(IGetDeviceInfoAidlInter iGetDeviceInfoInter) throws RemoteException {
            iGetDeviceInfoAidlInter = iGetDeviceInfoInter;
            getDeviceInfoTask();
        }

        @Override
        public String getOtaStatus() throws RemoteException {
            return OtaStatusMgr.getInstance().getCurStatus().toString();
        }

        @Override
        public void checkVersion(ICheckVersionAidlInter iCheckVersionListener) throws RemoteException {
            iCheckVersionAidlInter = iCheckVersionListener;
            checkVersionTask();
        }

        @Override
        public void download(IDownloadAidlInter iDownloadListener) throws RemoteException {
            iDownloadAidlInter = iDownloadListener;
            downloadTask();
        }

        @Override
        public void pauseDownload() throws RemoteException {
            pauseDownloadTask();
        }

        @Override
        public void install(IUpdateAidlInter updateAidlInter) throws RemoteException {
            iUpdateAidlInter = updateAidlInter;
            installTask();
        }
    };

    private void pauseDownloadTask() {
        if (!aidlPrepare()) {
            return;
        }
        otaBinder.downloadCancel();
    }

    private void getDeviceInfoTask() {
        DeviceAidlInfo deviceAidlInfo = new DeviceAidlInfo();
        DeviceInfo deviceInfo = null;
        ProductInfo productInfo = null;
        try {
            deviceInfo = OtaAgentPolicy.getOtaEntityController().getMainEntity().getDeviceInfo();
            productInfo = OtaAgentPolicy.getOtaEntityController().getMainEntity().getProductInfo();
        } catch (Exception e) {
            return;
        }
        deviceAidlInfo.mid = OtaAgentPolicy.getParamsController().getParams().mid;
        deviceAidlInfo.oem = deviceInfo.oem;
        deviceAidlInfo.models = deviceInfo.models;
        deviceAidlInfo.platform = deviceInfo.platform;
        deviceAidlInfo.deviceType = deviceInfo.deviceType;
        deviceAidlInfo.version = deviceInfo.version;
        deviceAidlInfo.productId = productInfo.productId;
        deviceAidlInfo.productSecret = productInfo.productSecret;
        if (null != iGetDeviceInfoAidlInter) {
            try {
                iGetDeviceInfoAidlInter.onSuccess(deviceAidlInfo);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Trace.d(TAG, "onBind() ");
        return iOtaInter;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Trace.d(TAG, "onUnbind() ");
        return super.onUnbind(intent);
    }

    @Override
    public void onCreate() {
        Trace.d(TAG, "onCreate() ");
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        Trace.d(TAG, "onDestroy() ");
        super.onDestroy();
    }

    /**
     * 是否和OTAService建立连接
     *
     * @return
     */
    private boolean aidlPrepare() {
        if (otaBinder == null) {
            Intent intent = new Intent(this, OtaService.class);
            bindService(intent, connection, Context.BIND_AUTO_CREATE);
            RxTime.newInstance().setTimeout(5 * 1000)
                    .setPeriod(2 * 100)
                    .setICondition(() -> otaBinder != null).execute();
            return otaBinder != null;
        }
        return true;
    }
}
